﻿using System.Linq;
using System.Web.Mvc;
using ASPItalia.ModelVirtualCasting.ObjectModel;
using ASPItalia.ModelVirtualCasting.Web.Filters;
using ASPItalia.ModelVirtualCasting.Common;
using System;
using System.Collections.Generic;
using ASPItalia.ModelVirtualCasting.Web.Models;

namespace ASPItalia.ModelVirtualCasting.Web.Controllers
{
    [ProvideCountriesAttribute]
    public class CandidateController : Controller
    {
        #region Creazione candidate
        public ActionResult SmartCreate()
        {
            return View();
        }

        [HttpPost]
        public ActionResult SmartCreate(Candidate candidate)
        {
            if (!this.ModelState.IsValid)
            {
                return View();
            }
            
            ICandidateRepository repository = ApplicationContext.Current.Candidates;
            repository.InsertOnSubmit(candidate);
            repository.SubmitChanges();

            TempData["Message"] = "Profilo salvato correttamente";

            return this.RedirectToAction("Profile", new { nickname = candidate.NickName });
        }
        #endregion

        #region Show profilo
        public ActionResult Profile(string nickname)
        {
            var candidate = this.getCandidateByNick(nickname);
			this.ViewData.Model = candidate ?? new Candidate();

			if (candidate == null)
				this.TempData["Message"] = "Hai per caso provato a taroccare la URL???";

            #region AJAX
            if (Request.IsAjaxRequest())
                return this.View("ShowCandidate");
            #endregion

            return this.View();
        }

        private Candidate getCandidateByNick(string nickname)
        {
            ICandidateRepository repository = ApplicationContext.Current.Candidates;
            // Candidate candidate = repository.GetByNickname(nickname);

            Candidate candidate = repository
                .Include("Multimedia", "NationalityCountry", "ResidenceCountry")
                .Where(c => c.NickName.ToLower() == nickname.ToLower()).SingleOrDefault();

            return candidate;
        }

        public ActionResult ShowPics(string nickname)
        {
            ICandidateRepository repository = ApplicationContext.Current.Candidates;

            // Candidate candidate = repository.Include("Multimedia").GetByNickname(nickname);
            Candidate candidate = repository.Include("Multimedia").Where(c => c.NickName.ToLower() == nickname.ToLower()).Single();

            this.ViewData.Model = candidate;

            return this.View();
        }
        #endregion

        #region Modifica profilo
        public ActionResult Edit(string nickname)
        {
            return this.View(this.getCandidateByNick(nickname));
        }

        [HttpPost]
        public ActionResult Edit(string nickname, Candidate candidate)
        {
            if (!this.ModelState.IsValid)
            {
                return View();
            }

            Candidate original = this.getCandidateByNick(nickname);
            this.UpdateModel(original, new string[] 
                { 
                    "FirstName",
                    "LastName",
                    "EmailAddress",
                    "BirthDate",
                    "CanBeNaked",
                    "Gender",
                    "PhysicalProfile"
                });
            original.ResidenceCountryID = candidate.ResidenceCountry.CountryID;
            original.NationalityCountryID = candidate.NationalityCountry.CountryID;

            ICandidateRepository repository = ApplicationContext.Current.Candidates;
            repository.SubmitChanges();

            return this.RedirectToAction("Index", "Home");
        }
        #endregion

        #region Search
        [HttpGet]
        [ProvideCountries]
        public ActionResult Search()
        {
            return View(new SearchCandidateModel());
        }

        [HttpPost]
        public ActionResult Search(SearchCandidateModel model)
        {
            // in questo modo diamo all'utente la possibilità
            // di salvare la ricerca tra i bookmark
            string searchFilter = model.Serialize();

            return this.RedirectToAction("Results", new { filter = searchFilter });
        }

        public ActionResult Results(string filter, int? pageNumber)
        {
            if (pageNumber == null)
                pageNumber = 1;

            /* si può usare anche dentro un blocco try..catch per 
             * gestire dati di input non validi */
            SearchCandidateModel searchCandidateModel =
                SearchCandidateModel.Deserialize(filter);

            ICandidateRepository repository = ApplicationContext.Current.Candidates;
            
            var query = repository.Include("ResidenceCountry").GetAll();

            if (!string.IsNullOrEmpty(searchCandidateModel.Nickname))
            {
                query = query.Where(c => c.NickName.StartsWith(searchCandidateModel.Nickname));
            }

            if (!string.IsNullOrEmpty(searchCandidateModel.Firstname))
            {
                query = query.Where(c => c.FirstName.StartsWith(searchCandidateModel.Firstname));
            }

            if (!string.IsNullOrEmpty(searchCandidateModel.Gender))
            {
                query = query.Where(c => c.Gender == searchCandidateModel.Gender);
            }

            if (searchCandidateModel.CurrentCountry.CountryID > 0)
            {
                query = query.Where(c => c.ResidenceCountry.CountryID == searchCandidateModel.CurrentCountry.CountryID);
            }

            // e così via...
            int totalPages = (int)Math.Ceiling(Convert.ToDecimal(query.Count()) / pageSize);
            query = query
                .OrderBy(c => c.NickName)
                .Skip((pageNumber.Value - 1) * pageSize)
                .Take(pageSize);

            SearchCandidateResult model = new SearchCandidateResult(pageNumber.Value, totalPages, query);
            model.BaseUrl = Url.Action("Results", new { filter = filter, pageNumber = "[page]" });
            
            return this.View(model);
        }

        private const int pageSize = 3;
        #endregion
    }
}
